package org.example.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.example.config.ApiConfig;
import org.example.util.constantUtil.ConstantUtil;
import org.example.util.DeviceUtil;
import org.example.util.HttpClientUtil;
import org.example.util.Result;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import static org.example.enums.ResultCode.FAIL;
import static org.example.enums.ResultCode.SUCCESS;

@Slf4j
@Service
public class TimeseriesService {
    @Autowired
    private ApiConfig apiConfig;

    private static final long OFFSET_SN=787986650000L;
    private static final String INVALID_DATA=ConstantUtil.INVALID_DATA;

    /**
     * 去掉前缀N
     * @param str
     * @return
     */
    public static String cutPre(String str){
        if(str==null){
            return null;
        }
        char first=str.charAt(0);
        if(first=='N'){
            str=str.substring(1,str.length());
        }
        return str;
    }
    /**
     * 预处理，将编码转换为8bit一组的16进制字符串数组
     * @param hexString
     * @return
     */
    public static String[] preprocess(String hexString){

        if (hexString == null || hexString.equals("")) {
            return null;
        }
        hexString=cutPre(hexString);
        hexString = hexString.trim().replaceAll("\\s*", ""); // 去除字符串中的空格
        hexString=hexString.replaceAll("N","");
        hexString=hexString.toUpperCase();// 大写
//        System.out.println(hexString);
        String[] code=new String[hexString.length()/2];
        int i=0;

        try{
            while(true){
                code[i]=hexString.substring(0,2);//取前两个字符
//            System.out.println("code"+i+" "+code[i]);
                i++;
                hexString=hexString.substring(2,hexString.length());
                if(hexString == null || hexString.equals("")){
                    break;
                }
            }
        }
        catch (StringIndexOutOfBoundsException e){
            log.error("StringIndexOutOfException:",hexString,e);
            return null;
        }
//        for(String s:code){
//            System.out.print(s);
//        }
//        System.out.println();
        return code;
    }

    /**
     * 将temp存到数组中并返回
     * @param result 已存入的数据便于查询温度个数
     * @param tempNum 温度个数的字段名
     * @param tempCode 温度的value
     * @return
     */
    private static List<Integer> getTemps(Map<String,Object> result,String tempNum,String tempCode){
        List<Integer> temps=new LinkedList<>();
        if(result.get(tempNum)!=null&&tempCode!=null){
            String[] code=preprocess(tempCode);
            int num=(Integer) result.get(tempNum);
            for(int i=0;i<code.length;i++){//1个envTemp占1个字节
                if(Integer.parseInt(code[i],16)==0){//0的话说明没有
                    temps.add(0);
                }else {//非0则偏移40度
                    temps.add(Integer.parseInt(code[i],16)-40);//偏移40度
                }
            }
        }
        return temps;
    }

    /**
     * 转换以16进制ascii表示的编码
     * @param hexAscii
     * @return
     */
    public static String dealHexAscii(String hexAscii){
        String[] code=preprocess(hexAscii);
        String resultStr="";
        for(int i=0;i<code.length;i++){
            resultStr+=Character.toString((char) Integer.parseInt(code[i],16));
        }
        return resultStr;
    }

    /**
     * String转换为16进制ascii码
     * @param input
     * @return
     */
    public static String stringToHexAscii(String input) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < input.length(); i++) {
            char c = input.charAt(i);
            String hex = Integer.toHexString((int) c);
            sb.append(hex.toUpperCase());
        }
        return sb.toString();
    }

    /**
     * 判断是否为全1（0xFFFF）
     * @param hexString 去掉前缀N的16进制字符串
     * @return 结果是否为全1
     */
    public static Boolean isAllOne(String hexString){
        hexString=hexString.toUpperCase();
        for(int i=0;i<hexString.length();i++){
            if(hexString.charAt(i) !='F'){
                return false;
            }
        }
        return true;
    }


    /**
     * B1帧处理，传入原始带N前缀的编码，输出String表示的对应类型
     */

    /**
     * 1.总电压处理 rackTotalVoltage 类型 Double
     * @param origin 带N的原始字符串，例：jsonResult.getJSONArray("rackTotalVoltage").getJSONObject(0).get("value").toString()
     * @return 以字符串表示的10进制Double
     */
    public static String dealRackTotalVoltage(String origin){
        // 非空判断
        if(origin==null)
            return null;
        // 无效数据判断0xFFFF
        if(isAllOne(cutPre(origin))){
            // 此时数据无效
            return INVALID_DATA;
        }
        //此时单位为0.01V  1248=4680
        BigDecimal totalVol=new BigDecimal(Integer.parseInt(cutPre(origin),16));
        BigDecimal d=new BigDecimal(100);
        //要求单位为1V  4680*0.01V=46.8V
        return totalVol.divide(d).toString();
    }

    /**
     * 2.总电流处理 rackTotalCurrent 类型Double
     * @param origin 带N的原始字符串，例：jsonResult.getJSONArray("rackTotalVoltage").getJSONObject(0).get("value").toString()
     * @return 以字符串表示的10进制Double
     */
    public static String dealRackTotalCurrent(String origin){
        if(origin==null)
            return null;
        // 无效数据判断0xFFFF
        if(isAllOne(cutPre(origin))){
            // 此时数据无效
            return INVALID_DATA;
        }
        //此时单位为0.01A 7530=30000
        BigDecimal totalCur=new BigDecimal(Integer.parseInt(cutPre(origin),16));
        BigDecimal d=new BigDecimal(100);
        BigDecimal sub=new BigDecimal(300);
        // 转换为1A 并且有300A的偏移  30000*0.01-300=300-300=0
        return totalCur.divide(d).subtract(sub).toString();
    }
    /**
     * 3.充电状态处理 Battery_Status 类型Integer
     * @param origin 带N的原始字符串
     * @return 以字符串表示的10进制整数
     */
    public static String dealBatteryStatus(String origin){
        if(origin==null)
            return null;
        if(isAllOne(cutPre(origin))){
            // 此时数据无效
            return INVALID_DATA;
        }
        return String.valueOf(Integer.parseInt(cutPre(origin),16)); // C:43->67 D:44->68 N:4E->78
    }

    /**
     * 4&5 处理电池电量和健康度SOC和SOH racketSOC和racketSOH 类型Double
     * @param origin
     * @return
     */
    public static String dealRacketSOCAndSOH(String origin){
        if(origin==null)
            return null;
        if(isAllOne(cutPre(origin))){
            // 此时数据无效
            return INVALID_DATA;
        }
        return String.valueOf(Integer.parseInt(cutPre(origin),16));
    }

    /**
     * 6&8 处理最大和最小单体电压 maxCellVoltage和minCellVoltage 类型 Integer
     * @param origin
     * @return
     */
    public static String dealMaxCellVoltage(String origin){
        if(origin==null)
            return null;
        if(isAllOne(cutPre(origin))){
            // 此时数据无效
            return INVALID_DATA;
        }
        return String.valueOf(Integer.parseInt(cutPre(origin),16));
    }
    public static String dealMinCellVoltage(String origin){
        if(origin==null)
            return null;
        if(isAllOne(cutPre(origin))){
            // 此时数据无效
            return INVALID_DATA;
        }
        return String.valueOf(Integer.parseInt(cutPre(origin),16));
    }
    /**
     * 7&9 处理最大最小单体电压位置 maxCellVoltageCellid和minCellVoltageCellid 类型 Integer
     * @param origin
     * @return
     */
    public static String dealMaxCellVoltageCellid(String origin){
        if(origin==null)
            return null;
        if(isAllOne(cutPre(origin))){
            // 此时数据无效
            return INVALID_DATA;
        }
        return String.valueOf(Integer.parseInt(cutPre(origin),16));
    }
    public static String dealMinCellVoltageCellid(String origin){
        if(origin==null)
            return null;
        if(isAllOne(cutPre(origin))){
            // 此时数据无效
            return INVALID_DATA;
        }
        return String.valueOf(Integer.parseInt(cutPre(origin),16));
    }

    /**
     * 10&12 处理最高和最低温度 maxTemp和minTemp 类型Double
     * @param origin
     * @return
     */
    public static String dealMaxTemp(String origin){
        if(origin==null)
            return null;
        if(isAllOne(cutPre(origin))){
            // 此时数据无效
            return INVALID_DATA;
        }
        return String.valueOf(Integer.parseInt(cutPre(origin),16)-40);
    }
    public static String dealMinTemp(String origin){
        if(origin==null)
            return null;
        if(isAllOne(cutPre(origin))){
            // 此时数据无效
            return INVALID_DATA;
        }
        return String.valueOf(Integer.parseInt(cutPre(origin),16)-40);
    }
    /**
     * 11&13 处理最大最小单体电压位置 maxCellTempCellid和minCellTempCellid 类型Integer
     * @param origin
     * @return
     */
    public static String dealMaxCellTempCellid(String origin){
        if(origin==null)
            return null;
        if(isAllOne(cutPre(origin))){
            // 此时数据无效
            return INVALID_DATA;
        }
        return String.valueOf(Integer.parseInt(cutPre(origin),16));
    }
    public static String dealMinCellTempCellid(String origin){
        if(origin==null)
            return null;
        if(isAllOne(cutPre(origin))){
            // 此时数据无效
            return INVALID_DATA;
        }
        return String.valueOf(Integer.parseInt(cutPre(origin),16));
    }

    /**
     * 14.处理一级报警和二级报警 firstError和secondError
     * @param origin
     * @return
     */
    public static String dealError(String origin){
        if(origin==null)
            return null;
        if(isAllOne(cutPre(origin))){
            // 此时数据无效0xFFFFFFFF
            return INVALID_DATA;
        }
        // 只需要cutPre不需要16进制转换，保持原数据
        return cutPre(origin);
    }

    /**
     * 15. 处理MOS状态 mosSwitch 只需要cutPre
     * @param origin
     * @return
     */
    public static String dealMosSwitch(String origin){
        if(origin==null)
            return null;
        if(isAllOne(cutPre(origin))){
            // 此时数据无效0xFF
            return INVALID_DATA;
        }
        // 只需要cutPre不需要16进制转换，保持原数据
        return cutPre(origin);
    }

    /**
     * 16.输入状态inputSwitch 只需要cutPre
     * @param origin
     * @return
     */
    public static String dealInputSwitch(String origin){
        if(origin==null)
            return null;
        if(isAllOne(cutPre(origin))){
            // 此时数据无效0xFF
            return INVALID_DATA;
        }
        // 只需要cutPre不需要16进制转换，保持原数据
        return cutPre(origin);
    }

    /**
     * 17.电池电压个数 volsNum
     * @param origin
     * @return
     */
    public static String dealVolsNum(String origin){
        if(origin==null)
            return null;
        // 18.电池电压为无效数据时电压个数为0，所以不需要判断无效数据
        return String.valueOf(Integer.parseInt(cutPre(origin),16));
    }

    /**
     * 19.电芯温度个数 cellTempNum
     * @param origin
     * @return
     */
    public static String dealCellTempNum(String origin){
        if(origin==null)
            return null;
        // 20.电芯温度为无效数据时电芯温度个数为0，所以不需要判断无效数据
        return String.valueOf(Integer.parseInt(cutPre(origin),16));
    }
    /**
     * 21.环境温度个数 envTempNum
     * @param origin
     * @return
     */
    public static String dealEnvTempNum(String origin){
        if(origin==null)
            return null;
        // 22.环境温度为无效数据时环境温度个数为0，所以不需要判断无效数据
        return String.valueOf(Integer.parseInt(cutPre(origin),16));
    }
    /**
     * 23.mos温度个数 mosTempNum
     * @param origin
     * @return
     */
    public static String dealMosTempNum(String origin){
        if(origin==null)
            return null;
        // 24.mos温度为无效数据时环境温度个数为0，所以不需要判断无效数据
        return String.valueOf(Integer.parseInt(cutPre(origin),16));
    }

    /**
     * 25.剩余容量 capacityRemain
     * @param origin
     * @return
     */
    public static String dealCapacityRemain(String origin){
        // 非空判断
        if(origin==null)
            return null;
        // 无效数据判断0xFFFF
        if(isAllOne(cutPre(origin))){
            // 此时数据无效
            return INVALID_DATA;
        }
        //此时单位为0.01A  1248=4680
        BigDecimal capacityRemain=new BigDecimal(Integer.parseInt(cutPre(origin),16));
        BigDecimal d=new BigDecimal(100);
        //要求单位为1V  4680*0.01V=46.8V
        return capacityRemain.divide(d).toString();
    }

    /**
     * 26.电池包循环次数 cycleNum 类型Integer
     * @param origin
     * @return
     */
    public static String dealCycleNum(String origin){
        if(origin==null)
            return null;
        // 无效数据判断0xFFFF
        if(isAllOne(cutPre(origin))){
            // 此时数据无效
            return INVALID_DATA;
        }
        return String.valueOf(Integer.parseInt(cutPre(origin),16));
    }

    /**
     * 27&28.充放电量处理，0.1AH转换为AH
     * @param origin 带N的原始字符串
     * @return 转换完的String类型整数
     */
    public static String dealElectricSum(String origin){
        if(origin==null){
            return null;
        }
        // 无效数据判断0xFFFF
        if(isAllOne(cutPre(origin))){
            // 此时数据无效
            return INVALID_DATA;
        }
        origin=cutPre(origin);
        BigDecimal d=new BigDecimal(100);
        //默认单位0.01AH 如123=123*0.01AH，转换为AH 123=1.23AH
        BigDecimal electricSum=new BigDecimal(Long.parseLong(origin,16));  // 暂时改成Long
        return electricSum.divide(d).toString();
    }

    /**
     * 29.GPS/LBS定位状态 gps_lps 始终有效
     * @param origin
     * @return
     */
    public static String dealGPSLPS(String origin){
        if(origin==null){
            return null;
        }
        // 始终有效
        return cutPre(origin);
    }

    /**
     * 30&31&32&33 经纬度与经纬度格式 longitude&latitude&ewflag&nsflag
     * @param origin
     * @return
     */
    public static String dealLongAndLat(String origin){
        if(origin==null){
            return null;
        }
        // 始终有效
        return dealHexAscii(cutPre(origin));
    }

    /**
     * 34.海拔高度
     * @param origin
     * @return
     */
    public static String dealAltitude(String origin){
        if(origin==null){
            return null;
        }
        // 始终有效
        return String.valueOf(Integer.parseInt(cutPre(origin),16));
    }
    /**
     * 35.GPS速度
     * @param origin
     * @return
     */
    public static String dealSpeed(String origin){
        if(origin==null){
            return null;
        }
        // 始终有效
        return String.valueOf(Integer.parseInt(cutPre(origin),16));
    }




    /**
     * 36.里程处理distance
     * @param origin 带N的原始字符串，例：(String) distanceInfo.getJSONObject(0).get("value")
     * @return 以字符串表示的10进制整数
     */
    public static String dealDistance(String origin){
        if(origin==null)
            return null;
        // 始终有效
        return String.valueOf(Long.parseLong(cutPre(origin),16));  // 暂时改成Long
    }

    /**
     * 37. 4G 通讯信号强度
     * @param origin
     * @return
     */
    public static String dealSignalIntensity(String origin){
        if(origin==null)
            return null;
        // 始终有效
        return String.valueOf(Integer.parseInt(cutPre(origin),16));
    }

    /**
     * 38.电池状态标志 chargeFlag
     * @param origin
     * @return
     */
    public static String dealChargeFlag(String origin){
        return dealBatteryStatus(origin);
    }

    /**
     * 39.充电桩编号 chargeStationNo
     * @param origin
     * @return
     */
    public static String dealChargeStationNo(String origin){
        if(origin==null)
            return null;
        // 始终有效
        return String.valueOf(dealHexAscii(origin));
    }

    /**
     * 行驶(放电)时长、充电时长处理
     * @param origin 带N的原始字符串
     * @return 以字符串表示的10进制整数
     */
    public static String dealDischargeTime(String origin){
        if(origin==null)
            return null;
        // 无效数据判断0xFFFF
        if(isAllOne(cutPre(origin))){
            // 此时数据无效
            return INVALID_DATA;
        }
        return String.valueOf(Long.parseLong(cutPre(origin),16));
    }
    public static String dealChargeTime(String origin){
        if(origin==null)
            return null;
        // 无效数据判断0xFFFF
        if(isAllOne(cutPre(origin))){
            // 此时数据无效
            return INVALID_DATA;
        }
        return String.valueOf(Long.parseLong(cutPre(origin),16));
    }

    /**
     * 充行时长比
     * @param origin 带N的原始字符串
     * @return 以字符串表示的10进制整数
     */
    public static String dealchargeTravelRatio(String origin){
        if(origin==null)
            return null;
        // 无效数据判断0xFFFF
        if(isAllOne(cutPre(origin))){
            // 此时数据无效
            return INVALID_DATA;
        }
        return String.valueOf(Long.parseLong(cutPre(origin),16));
    }

    /**
     *  充电次数处理
     * @param origin 带N的原始字符串
     * @return 以字符串表示的10进制整数
     */
    public static String dealChargeNum(String origin){
        if(origin==null)
            return null;
        // 无效数据判断0xFFFF
        if(isAllOne(cutPre(origin))){
            // 此时数据无效
            return INVALID_DATA;
        }
        return String.valueOf(Long.parseLong(cutPre(origin),16));
    }






    /**
     * 单独获取packNo和ts
     * @param uuid
     * @param token
     * @return
     */
    public Map<String, String> getPackSN(String uuid, String token){
        Map<String,String> result=new HashMap<>();
        String url= apiConfig.getDataApiPrefix()+uuid+apiConfig.getDataApiSuffix();
        String[] resultStr = HttpClientUtil.get_data(url, token);//String 格式获取结果, [0]为statusCode，[1]为结果(结果可能不是json)
        if (Integer.valueOf(resultStr[0]) != 200) {//没有正确拿到信息
            log.error("/api/plugins/telemetry/DEVICE/ code:" + resultStr[0] + " result:" + resultStr[1]);
            try {//错误但是返回json格式
                //尝试拿数据
                if(resultStr[1]==null){  // 错误信息为null
                    result.put("message","resultStr[1] is null!");
                    result.put("uuid",uuid);
                    return result;
                }
                JSONObject jsonResult = JSONObject.parseObject(resultStr[1]);
//                System.out.println(jsonResult);
                //若查询到JSON数据
                result.put("code",resultStr[0]);

                // 错误信息不为null但是没有message项
                if(!jsonResult.containsKey("message")){
                    result.put("message",resultStr[1]);
                    result.put("uuid",uuid);
                    return result;
                }
                // 有message项
                result.put("message",jsonResult.get("message").toString());
                result.put("uuid",uuid);
                return result;
            } catch (JSONException e) {//错误而且返回的不是JSON格式
//                System.out.println("resultStr: "+resultStr);
                result.put("code",resultStr[0]);
                result.put("message",resultStr[1]);
                result.put("uuid",uuid);
                return result;
            }
        }
        else {
            JSONObject jsonResult = JSONObject.parseObject(resultStr[1]);
            // 电池包编码 ASCII表示
            try{
                result.put("PACK_SN",cutPre(dealHexAscii(cutPre(jsonResult.getJSONArray("PACK_SN").getJSONObject(0).get("value").toString()))));
                result.put("Life_ts",jsonResult.getJSONArray("PACK_SN").getJSONObject(0).get("ts").toString());
            }
            catch (NullPointerException e){
                log.warn(uuid," Cannot get PACK_SN",e);
            }
        }
        return result;
    }

    /**
     * 单独获取OnOffStatus所需的数据（未开发）
     * @param uuid
     * @param token
     * @return
     */
    public static Map<String,Object> getOnOffStatusInfo(String uuid,String token){

        return null;
    }

    /**
     * 获取数据库字段数据
     * @param uuid
     * @param token
     * @return
     */
    public Map<String,Object> getTimeseries(String uuid,String token){
        Map<String,Object> result=new HashMap<>();

        String url=apiConfig.getDataApiPrefix()+uuid+apiConfig.getDataApiSuffix();
        System.out.println(url);
        String[] resultStr = HttpClientUtil.get_data(url, token);//String 格式获取结果, [0]为statusCode，[1]为结果(结果可能不是json)
        if (Integer.valueOf(resultStr[0]) != 200) {//没有正确拿到信息
            // 此处返回的错误信息中一定要含有非null的"message"项，否则外部无法判断出错
            log.error("code:" + resultStr[0] + " result:" + resultStr[1]);
            try {//错误但是返回json格式
                //尝试拿数据
                if(resultStr[1]==null){  // 错误信息为null
                    result.put("message","resultStr[1] is null!");
                    result.put("uuid",uuid);
                    return result;
                }
                JSONObject jsonResult = JSONObject.parseObject(resultStr[1]);
//                System.out.println(jsonResult);
                //若查询到JSON数据
                result.put("code",resultStr[0]);

                // 错误信息不为null但是没有message项
                if(!jsonResult.containsKey("message")){
                    result.put("message",resultStr[1]);
                    result.put("uuid",uuid);
                    return result;
                }
                // 有message项
                result.put("message",jsonResult.get("message").toString());
                result.put("uuid",uuid);
                return result;
            } catch (JSONException e) {//错误而且返回的不是JSON格式
//                System.out.println("resultStr: "+resultStr);
                result.put("code",resultStr[0]);
                if(resultStr[1]==null){
                    result.put("message","resultStr[1] is null!");
                    result.put("uuid",uuid);
                } else{
                    result.put("message",resultStr[1]);
                    result.put("uuid",uuid);
                }
                return result;
            }
        }else {
            result.put("imei", DeviceUtil.getKey(uuid));
            System.out.println("resultCode=200 imei="+DeviceUtil.getKey(uuid)+" uuid="+uuid);
            //尝试拿数据
            JSONObject jsonResult = JSONObject.parseObject(resultStr[1]);
            /**
             * A1帧
             */
            // BMS软件版本
            try{
                result.put("SOFT_BMS",cutPre(jsonResult.getJSONArray("SOFT_BMS").getJSONObject(0).get("value").toString()));
            }
            catch (NullPointerException e){
                log.warn(uuid," Cannot get SOFT_BMS",e);
            }
            // BMS硬件版本
            try{
                result.put("HARD_BMS",cutPre(jsonResult.getJSONArray("HARD_BMS").getJSONObject(0).get("value").toString()));
            }
            catch (NullPointerException e){
                log.warn(uuid," Cannot get HARD_BMS",e);
            }
            // 4G软件版本
            try{
                result.put("SOFT_4G",cutPre(jsonResult.getJSONArray("SOFT_4G").getJSONObject(0).get("value").toString()));
            }
            catch (NullPointerException e){
                log.warn(uuid," Cannot get SOFT_4G",e);
            }
            // 4G硬件版本
            try{
                result.put("HARD_4G",cutPre(jsonResult.getJSONArray("HARD_4G").getJSONObject(0).get("value").toString()));
            }
            catch (NullPointerException e){
                log.warn(uuid," Cannot get HARD_4G",e);
            }
            // 4G_SN
            try{
                // 偏移787986650000
                long sn_4G=Long.parseLong(cutPre(jsonResult.getJSONArray("SN_4G").getJSONObject(0).get("value").toString()),16)+OFFSET_SN;
                result.put("SN_4G",String.valueOf(sn_4G));
            }
            catch (NullPointerException e){
                log.warn(uuid," Cannot get 4G_SN",e);
            }
            // SN_BMS
            try{
                // 偏移787986650000
                long sn_bms=Long.parseLong(cutPre(jsonResult.getJSONArray("SN_BMS").getJSONObject(0).get("value").toString()),16)+OFFSET_SN;
                result.put("SN_BMS",String.valueOf(sn_bms));
            }
            catch (NullPointerException e){
                log.warn(uuid," Cannot get SN_BMS",e);
            }
            //SIM卡 ICCID
            try{
                result.put("SIM_ICCID",dealHexAscii(cutPre(jsonResult.getJSONArray("SIM_ICCID").getJSONObject(0).get("value").toString())));
            }
            catch (NullPointerException e){
                log.warn(uuid," Cannot get SIM_ICCID",e);
            }
            //SIM卡 IMSI
            try{
                result.put("SIM_IMSI",dealHexAscii(cutPre(jsonResult.getJSONArray("SIM_IMSI").getJSONObject(0).get("value").toString())));
            }
            catch (NullPointerException e){
                log.warn(uuid," Cannot get SIM_IMSI",e);
            }
            // 电池设计容量 单位0.01AH
            try{
                result.put("capacity",cutPre(jsonResult.getJSONArray("capacity").getJSONObject(0).get("value").toString()));
            }
            catch (NullPointerException e){
                log.warn(uuid," Cannot get capacity",e);
            }
            //电池包串数
            try{
                int racket_num=Integer.parseInt(cutPre(jsonResult.getJSONArray("racket_num").getJSONObject(0).get("value").toString()),16);
                result.put("racket_num",String.valueOf(racket_num));
            }
            catch (NullPointerException e){
                log.warn(uuid," Cannot get racket_num",e);
            }
            //BMS PCB批次 ASCII表示
            try{
                result.put("BMS_pcbBatch",dealHexAscii(cutPre(jsonResult.getJSONArray("BMS_pcbBatch").getJSONObject(0).get("value").toString())));
            }
            catch (NullPointerException e){
                log.warn(uuid," Cannot get BMS_pcbBatch",e);
            }
            // 电池类型
            try{
                result.put("battery_type",cutPre(jsonResult.getJSONArray("battery_type").getJSONObject(0).get("value").toString()));
            }
            catch (NullPointerException e){
                log.warn(uuid," Cannot get battery_type",e);
            }
            // 电池包编码长度
            try{
                result.put("PACK_SN_len",cutPre(jsonResult.getJSONArray("PACK_SN_len").getJSONObject(0).get("value").toString()));
            }
            catch (NullPointerException e){
                log.warn(uuid," Cannot get PACK_SN_len",e);
            }
            // 电池包编码 ASCII表示
            try{
                result.put("PACK_SN",cutPre(dealHexAscii(cutPre(jsonResult.getJSONArray("PACK_SN").getJSONObject(0).get("value").toString()))));
            }
            catch (NullPointerException e){
                log.warn(uuid," Cannot get PACK_SN",e);
            }

            /**
             * B1帧
             */
            // 1.电池总压
            try{
                result.put("rackTotalVoltage",dealRackTotalVoltage(jsonResult.getJSONArray("rackTotalVoltage").getJSONObject(0).get("value").toString()));
                result.put("rackTotalVoltage_ts",jsonResult.getJSONArray("rackTotalVoltage").getJSONObject(0).get("ts").toString());
                //随便挑了一个的ts作为Life
                result.put("Life_ts",jsonResult.getJSONArray("rackTotalVoltage").getJSONObject(0).get("ts").toString());
            }
            catch (NullPointerException e){
                log.warn(uuid," Cannot get rackTotalVoltage",e);
            }
            // 2.电池电流
            try{
                result.put("rackTotalCurrent",dealRackTotalCurrent(jsonResult.getJSONArray("rackTotalCurrent").getJSONObject(0).get("value").toString()));
            }
            catch (NullPointerException e){
                log.warn(uuid," Cannot get rackTotalCurrent",e);
            }
            // 3.电池状态 Integer
            try{
                result.put("Battery_Status",dealBatteryStatus(jsonResult.getJSONArray("Battery_Status").getJSONObject(0).get("value").toString()));
            }
            catch (NullPointerException e){
                log.warn(uuid," Cannot get SN_BMS",e);
            }
            // 4.SOC
            try{
                result.put("racketSOC",Integer.parseInt(dealRacketSOCAndSOH(jsonResult.getJSONArray("racketSOC").getJSONObject(0).get("value").toString())));
            }
            catch (NullPointerException e){
                log.warn(uuid," Cannot get racketSOC",e);
            }
            // 5.SOH
            try{
                result.put("racketSOH",Integer.parseInt(dealRacketSOCAndSOH(jsonResult.getJSONArray("racketSOH").getJSONObject(0).get("value").toString())));
            }
            catch (NullPointerException e){
                log.warn(uuid," Cannot get racketSOH",e);
            }
            // 6.最大单体电压
            try{
                result.put("maxCellVoltage",Integer.parseInt(dealMaxCellVoltage(jsonResult.getJSONArray("maxCellVoltage").getJSONObject(0).get("value").toString())));
            }
            catch (NullPointerException e){
                log.warn(uuid," Cannot get maxCellVoltage",e);
            }
            // 7.最大单体电压位置
            try{
                result.put("maxCellVoltageCellid",Integer.parseInt(dealMaxCellVoltageCellid(jsonResult.getJSONArray("maxCellVoltageCellid").getJSONObject(0).get("value").toString())));
            }
            catch (NullPointerException e){
                log.warn(uuid," Cannot get maxCellVoltageCellid",e);
            }
            // 8.最小单体电压
            try{
                result.put("minCellVoltage",Integer.parseInt(dealMinCellVoltage(jsonResult.getJSONArray("minCellVoltage").getJSONObject(0).get("value").toString())));
            }
            catch (NullPointerException e){
                log.warn(uuid," Cannot get minCellVoltage",e);
            }
            // 9.最小单体电压位置
            try{
                result.put("minCellVoltageCellid",Integer.parseInt(dealMinCellVoltageCellid(jsonResult.getJSONArray("minCellVoltageCellid").getJSONObject(0).get("value").toString())));
            }
            catch (NullPointerException e){
                log.warn(uuid," Cannot get minCellVoltageCellid",e);
            }
            // 10.单体最高温度值 40偏移
            try{
                result.put("maxTemp",Integer.parseInt(dealMaxTemp(jsonResult.getJSONArray("maxTemp").getJSONObject(0).get("value").toString())));
            }
            catch (NullPointerException e){
                log.warn(uuid," Cannot get maxTemp",e);
            }
            // 11.单体最高温度位置
            try{
                result.put("maxCellTempCellid",Integer.parseInt(dealMaxCellTempCellid(jsonResult.getJSONArray("maxCellTempCellid").getJSONObject(0).get("value").toString())));
            }
            catch (NullPointerException e){
                log.warn(uuid," Cannot get maxCellTempCellid",e);
            }
            //12.单体最低温度值 40偏移
            try{
                result.put("minTemp",Integer.parseInt(dealMinTemp(jsonResult.getJSONArray("minTemp").getJSONObject(0).get("value").toString())));
            }
            catch (NullPointerException e){
                log.warn(uuid," Cannot get minTemp",e);
            }
            // 13.单体最低温度位置
            try{
                result.put("minCellTempCellid",Integer.parseInt(dealMinCellTempCellid(jsonResult.getJSONArray("minCellTempCellid").getJSONObject(0).get("value").toString())));
            }
            catch (NullPointerException e){
                log.warn(uuid," Cannot get minCellTempCellid",e);
            }
            // 14-1.一级报警
            try{
                result.put("firstError",dealError(jsonResult.getJSONArray("firstError").getJSONObject(0).get("value").toString()));
                result.put("firstError_ts",jsonResult.getJSONArray("firstError").getJSONObject(0).get("ts").toString());
            }
            catch (NullPointerException e){
                log.warn(uuid," Cannot get FirstError",e);
            }
            // 14-2.二级报警
            try{
                result.put("secondError",dealError(jsonResult.getJSONArray("secondError").getJSONObject(0).get("value").toString()));
                result.put("secondError_ts",jsonResult.getJSONArray("secondError").getJSONObject(0).get("ts").toString());
            }
            catch (NullPointerException e){
                log.warn(uuid," Cannot get SecondError",e);
            }
            // 15.MOS状态
            try{
                result.put("mosSwitch",dealMosSwitch(jsonResult.getJSONArray("mosSwitch").getJSONObject(0).get("value").toString()));
            }
            catch (NullPointerException e){
                log.warn(uuid," Cannot get mosSwitch",e);
            }
            // 16.输入状态
            try{
                result.put("inputSwitch",dealInputSwitch(jsonResult.getJSONArray("inputSwitch").getJSONObject(0).get("value").toString()));
            }
            catch (NullPointerException e){
                log.warn(uuid," Cannot get inputSwitch",e);
            }
            //17.电池电压个数
            try{
                result.put("volsNum",Integer.parseInt(dealVolsNum(jsonResult.getJSONArray("volsNum").getJSONObject(0).get("value").toString())));
            }
            catch (NullPointerException e){
                log.warn(uuid," Cannot get volsNum",e);
            }
            // 18.电池电压&平均电压
            try{
                // 获取电池电压 Map<String,Integer> vols
                String volsCode=cutPre(jsonResult.getJSONArray("vols").getJSONObject(0).get("value").toString());
                Map<String,Integer> vols=new HashMap<>();
                if(result.get("volsNum")!=null&&volsCode!=null){
                    String[] code=preprocess(volsCode);
                    int volsNum=(Integer) result.get("volsNum");
                    double volSum=0;
                    for(int i=0;i<volsNum;i++){//1个电压占2个字节
                        vols.put("v"+String.valueOf(i+1),Integer.parseInt(code[i*2]+code[i*2+1],16));
                        volSum+=Integer.parseInt(code[i*2]+code[i*2+1],16);
                    }
                    //平均电压
                    double averageVolttage=0;
                    if(volsNum!=0){
                        averageVolttage=volSum/volsNum;
                    }
                    //单体平均电压
                    result.put("rackAverageVoltage",String.format("%.2f",averageVolttage));
                }
                result.put("vols",vols);
            }
            catch (NullPointerException e){
                log.warn(uuid," Cannot get vols",e);
            }
            // 19.电芯温度个数
            try{
                result.put("cellTempNum",Integer.parseInt(dealCellTempNum(jsonResult.getJSONArray("cellTempNum").getJSONObject(0).get("value").toString())));
            }
            catch (NullPointerException e){
                log.warn(uuid," Cannot get cellTempNum",e);
            }
            // 20.电芯温度 List<Integer> cellTemps
            try{
                // 获取电芯温度
                String celltempsCode=cutPre(jsonResult.getJSONArray("celltemps").getJSONObject(0).get("value").toString());
                List<Integer> cellTemps=getTemps(result,"cellTempNum",celltempsCode);;
                result.put("celltemps",cellTemps);
            }
            catch (NullPointerException e){
                log.warn(uuid," Cannot get cellTemps",e);
            }
            //21.环境温度个数
            try{
                result.put("envTempNum",Integer.parseInt(dealEnvTempNum(jsonResult.getJSONArray("envTempNum").getJSONObject(0).get("value").toString())));
            }
            catch (NullPointerException e){
                log.warn(uuid," Cannot get envTempNum",e);
            }
            //22.环境温度 List<Integer> envTemps
            try{
                // 获取环境温度
                String envtempsCode=cutPre(jsonResult.getJSONArray("envtemps").getJSONObject(0).get("value").toString());
                List<Integer> envTemps=getTemps(result,"envTempNum",envtempsCode);
                result.put("envTemps",envTemps);
            }
            catch (NullPointerException e){
                log.warn(uuid," Cannot get envTemp",e);
            }
            //23.MOS温度个数
            try{
                result.put("mosTempNum",Integer.parseInt(dealMosTempNum(jsonResult.getJSONArray("mosTempNum").getJSONObject(0).get("value").toString())));
            }
            catch (NullPointerException e){
                log.warn(uuid," Cannot get mosTempNum",e);
            }
            //24.MOS温度 List<Integer> mosTemps
            try{
                // 获取mos温度
                String mostempsCode=cutPre(jsonResult.getJSONArray("mostemps").getJSONObject(0).get("value").toString());
                List<Integer> mosTemps=getTemps(result,"mosTempNum",mostempsCode);
                result.put("mosTemps",mosTemps);
            }
            catch (NullPointerException e){
                log.warn(uuid," Cannot get mosTemp",e);
            }
            //25.剩余容量 单位0.01AH
            try{
                result.put("capacityRemain",dealCapacityRemain(jsonResult.getJSONArray("capacityRemain").getJSONObject(0).get("value").toString()));
            }
            catch (NullPointerException e){
                log.warn(uuid," Cannot get capacityRemain",e);
            }
            //26.电池包循环次数
            try{
                result.put("cycleNum",Integer.parseInt(dealCycleNum(jsonResult.getJSONArray("cycleNum").getJSONObject(0).get("value").toString())));
            }
            catch (NullPointerException e){
                log.warn(uuid," Cannot get cycleNum",e);
            }
            //27.累计放电容量
            try{
                result.put("electricDischargeSum",dealElectricSum(jsonResult.getJSONArray("electricDischargeSum").getJSONObject(0).get("value").toString()));
            }
            catch (NullPointerException e){
                log.warn(uuid," Cannot get electricDischargeSum",e);
            }
            //28.累计充电容量
            try{
                result.put("electricChargeSum",dealElectricSum(jsonResult.getJSONArray("electricChargeSum").getJSONObject(0).get("value").toString()));
            }
            catch (NullPointerException e){
                log.warn(uuid," Cannot get electricChargeSum",e);
            }
            //29.GPS/LBS定位状态
            try{
                result.put("gps_lps",dealGPSLPS(jsonResult.getJSONArray("gps_lps").getJSONObject(0).get("value").toString()));
            }
            catch (NullPointerException e){
                log.warn(uuid," Cannot get gps_lps",e);
            }
            // 32.经度
            try{
                String longitude=dealLongAndLat(jsonResult.getJSONArray("longitude").getJSONObject(0).get("value").toString());
                result.put("longitude",longitude);
                result.put("longitude_ts",jsonResult.getJSONArray("longitude").getJSONObject(0).get("ts").toString());
            }
            catch (NullPointerException e){
                log.warn(uuid," Cannot get Longitude",e);
            }
            // 33.纬度
            try{
                String latitude=dealLongAndLat(jsonResult.getJSONArray("latitude").getJSONObject(0).get("value").toString());
                result.put("latitude",latitude);
                result.put("latitude_ts",jsonResult.getJSONArray("latitude").getJSONObject(0).get("ts").toString());
            }
            catch (NullPointerException e){
                log.warn(uuid," Cannot get Latitude",e);
            }
            //30.经度（格式）
            try{
                result.put("ewflag",dealLongAndLat(jsonResult.getJSONArray("ewflag").getJSONObject(0).get("value").toString()));
            }
            catch (NullPointerException e){
                log.warn(uuid," Cannot get ewflag",e);
            }
            //31.纬度（格式）
            try{
                result.put("nsflag",dealLongAndLat(jsonResult.getJSONArray("nsflag").getJSONObject(0).get("value").toString()));
            }
            catch (NullPointerException e){
                log.warn(uuid," Cannot get nsflag",e);
            }
            // 34.海拔高度
            try{
                result.put("altitude",Integer.parseInt(dealAltitude(jsonResult.getJSONArray("altitude").getJSONObject(0).get("value").toString())));
            }
            catch (NullPointerException e){
                log.warn(uuid," Cannot get altitude",e);
            }
            //35.GPS速度
            try{
                result.put("speed",Integer.parseInt(dealSpeed(jsonResult.getJSONArray("speed").getJSONObject(0).get("value").toString())));
            }
            catch (NullPointerException e){
                log.warn(uuid," Cannot get speed",e);
            }
            // 36.GPS行驶里程数
            try{
                result.put("distance",Long.parseLong(dealDistance(jsonResult.getJSONArray("distance").getJSONObject(0).get("value").toString())));
            }
            catch (NullPointerException e){
                log.warn(uuid," Cannot get distance",e);
            }
            // 37. 4G通讯信号强度
            try{
                result.put("signalIntensity",Integer.parseInt(dealSignalIntensity(jsonResult.getJSONArray("signalIntensity").getJSONObject(0).get("value").toString())));
            }
            catch (NullPointerException e){
                log.warn(uuid," Cannot get signalIntensity",e);
            }

        }
        return result;
    }

    /**
     * 获取数据库历史数据
     * 直接返回原始数据，需要额外进行处理
     */
    public Result getTimeseriesHis(String uuid, String token, String params){
        if (uuid == null) {
            return new Result(FAIL.code, false, null, "Invalid UUID string: null");
        }
        String url = apiConfig.getDataApiPrefix() + uuid + apiConfig.getDataApiSuffix() ;
        if(params!=null && !params.isEmpty()){
            url=url + params;
        }
        log.info("getTimeseriesHis,url:{}",url);
//        System.out.println(url);
        String[] resultStr = HttpClientUtil.get_data(url, token);
        Map<String,String> result=new HashMap<>();
        if (Integer.valueOf(resultStr[0]) != 200) {//没有正确拿到信息
            log.error("code:" + resultStr[0] + " result:" + resultStr[1]);
            try {//错误但是返回json格式
                //尝试拿数据
                if(resultStr[1]==null){
                    return new Result(FAIL.code, false,null,"result[1] is null!");
                }
                JSONObject jsonResult = JSONObject.parseObject(resultStr[1]);
                // 错误信息不为null但是没有message项
                if(!jsonResult.containsKey("message")){
                    return new Result(FAIL.code, false,null,resultStr[1]);
                }
                // 有message项
                return new Result(FAIL.code, false, null,jsonResult.get("message").toString());
            } catch (JSONException e) {//错误而且返回的不是JSON格式
//                System.out.println("resultStr: "+resultStr);
                return new Result(FAIL.code, false,null,resultStr[1]);
            }
        }
        JSONObject resultJson = JSON.parseObject(resultStr[1]);
        return new Result(SUCCESS.code, true, resultJson, null);
    }
}
